import psutil
from datetime import datetime
from dwmbar.other import get_command_out


class BarItem:
    def __init__(
        self,
        filled: bool = False
    ) -> None:
        self.filled = bool(filled)
        self.out = ''

    def update(self) -> None:
        pass

    def __str__(self) -> str:
        return self.out

    def __bool__(self) -> bool:
        return self.filled


class TimeItem(BarItem):
    def __init__(self) -> None:
        super().__init__(True)

    def update(self) -> None:
        self.out = " " + datetime.now().strftime("%H:%M")


class RAMItem(BarItem):
    def __init__(self) -> None:
        """RAM in G"""
        super().__init__(True)
        self.divider = 2**30
        self.total = round(psutil.virtual_memory()[0] / self.divider, 1)

    def update(self) -> None:
        used = round(psutil.virtual_memory()[3] / self.divider, 1)
        self.out = f" {used}G"


class LayoutItem(BarItem):
    def __init__(self) -> None:
        super().__init__(True)

    def update(self) -> None:
        self.out = ' ' + get_command_out(
            "setxkbmap -query | grep layout"
        ).split()[-1].upper()


class CPUUsageItem(BarItem):
    def __init__(self) -> None:
        super().__init__(True)

    def update(self) -> None:
        usage = psutil.cpu_percent()
        usage = f"{usage}" if usage % 1 else f"{int(usage)}.0"
        self.out = f" {usage:0>4}%"


class DiskUsageItem(BarItem):
    def __init__(self, divider: int = 10**9) -> None:
        super().__init__(True)
        """Disk in GB"""
        self.divider = 10**9
        self.total = round(psutil.disk_usage('/').total / self.divider, 1)

    def update(self) -> None:
        used = round(psutil.disk_usage('/').used / self.divider, 1)
        self.out = F" {used}G/{self.total}G"


class BatteryItem(BarItem):
    def __init__(self, hide_if_full: bool = False) -> None:
        super().__init__(True)
        self.hide_if_full = hide_if_full

    def update(self) -> None:
        battery = psutil.sensors_battery()
        plugged = battery.power_plugged
        percent = int(battery.percent)
        self.out = f" {'#' if plugged else '*'}{percent}%"
        self.filled = False if self.hide_if_full and percent == 100 else True


class InfoItem(BarItem):
    def __init__(self, text: str) -> None:
        super().__init__(True)
        self.out = text
